home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DKBSRC.ARJ / MATRICES.C < prev    next >
C/C++ Source or Header  |  1991-05-04  |  10KB  |  333 lines

  1. /*****************************************************************************
  2. *
  3. *                                   matrices.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module contains code to manipulate 4x4 matrices.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     OMX              (613) 731-3419
  37. *     Mystic           (613) 596-4249  or  (613) 596-4772
  38. *
  39. *  Fidonet:   1:163/109.9
  40. *  Internet:  dbuck@ccs.carleton.ca
  41. *  The "You Can Call Me RAY" BBS    (708) 358-5611
  42. *
  43. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  44. *
  45. *     The "You Can Call Me RAY" BBS (708) 358-5611
  46. *     The Information Exchange BBS  (708) 945-5575
  47. *
  48. *****************************************************************************/
  49.  
  50.  
  51. #include "frame.h"
  52. #include "vector.h"
  53. #include "dkbproto.h"
  54.  
  55. #ifndef PI
  56. #define PI 3.141592653689793
  57. #endif
  58.  
  59. void MZero (result)
  60.    MATRIX *result;
  61.    {
  62. /* Initialize the matrix to the following values:
  63.    0.0   0.0   0.0   0.0
  64.    0.0   0.0   0.0   0.0
  65.    0.0   0.0   0.0   0.0
  66.    0.0   0.0   0.0   0.0
  67. */
  68.    register int i, j;
  69.  
  70.    for (i = 0 ; i < 4 ; i++)
  71.       for (j = 0 ; j < 4 ; j++)
  72.          (*result)[i][j] = 0.0;
  73.    }
  74.  
  75. void MIdentity (result)
  76.    MATRIX *result;
  77.    {
  78. /* Initialize the matrix to the following values:
  79.    1.0   0.0   0.0   0.0
  80.    0.0   1.0   0.0   0.0
  81.    0.0   0.0   1.0   0.0
  82.    0.0   0.0   0.0   1.0
  83. */
  84.    register int i, j;
  85.  
  86.    for (i = 0 ; i < 4 ; i++)
  87.      for (j = 0 ; j < 4 ; j++)
  88.         if (i == j)
  89.            (*result)[i][j] = 1.0;
  90.         else
  91.            (*result)[i][j] = 0.0;
  92.    }
  93.  
  94. void MTimes (result, matrix1, matrix2)
  95.    MATRIX *result, *matrix1, *matrix2;
  96.    {
  97.    register int i, j, k;
  98.    MATRIX temp_matrix;
  99.  
  100.    for (i = 0 ; i < 4 ; i++)
  101.       for (j = 0 ; j < 4 ; j++) {
  102.          temp_matrix[i][j] = 0.0;
  103.          for (k = 0 ; k < 4 ; k++)
  104.             temp_matrix[i][j] += (*matrix1)[i][k] * (*matrix2)[k][j];
  105.          }
  106.  
  107.    for (i = 0 ; i < 4 ; i++)
  108.       for (j = 0 ; j < 4 ; j++)
  109.          (*result)[i][j] = temp_matrix[i][j];
  110.    }
  111.  
  112. /*  AAC - These are not used, so they are commented out to save code space...
  113.  
  114. void MAdd (result, matrix1, matrix2)
  115.    MATRIX *result, *matrix1, *matrix2;
  116.    {
  117.    register int i, j;
  118.  
  119.    for (i = 0 ; i < 4 ; i++)
  120.       for (j = 0 ; j < 4 ; j++)
  121.          (*result)[i][j] = (*matrix1)[i][j] + (*matrix2)[i][j];
  122.    }
  123.  
  124. void MSub (result, matrix1, matrix2)
  125.    MATRIX *result, *matrix1, *matrix2;
  126.    {
  127.    register int i, j;
  128.  
  129.    for (i = 0 ; i < 4 ; i++)
  130.       for (j = 0 ; j < 4 ; j++)
  131.          (*result)[i][j] = (*matrix1)[i][j] - (*matrix2)[i][j];
  132.    }
  133.  
  134. void MScale (result, matrix1, amount)
  135. MATRIX *result, *matrix1;
  136. DBL amount;
  137. {
  138.    register int i, j;
  139.  
  140.    for (i = 0 ; i < 4 ; i++)
  141.       for (j = 0 ; j < 4 ; j++)
  142.      if (amount == 1.0)
  143.         (*result)[i][j] = (*matrix1)[i][j]; * just copy *
  144.      else
  145.             (*result)[i][j] = (*matrix1)[i][j] * amount;
  146.    return;
  147. }
  148. ... up to here! */
  149.  
  150. void MTranspose (result, matrix1)
  151.    MATRIX *result, *matrix1;
  152.    {
  153.    register int i, j;
  154.    MATRIX temp_matrix;
  155.  
  156.    for (i = 0 ; i < 4 ; i++)
  157.       for (j = 0 ; j < 4 ; j++)
  158.          temp_matrix[i][j] = (*matrix1)[j][i];
  159.  
  160.    for (i = 0 ; i < 4 ; i++)
  161.       for (j = 0 ; j < 4 ; j++)
  162.          (*result)[i][j] = temp_matrix[i][j];
  163.    }
  164.  
  165.  
  166. void MTransformVector (result, vector, transformation)
  167.    VECTOR *result, *vector;
  168.    TRANSFORMATION *transformation;
  169.    {
  170.    register int i;
  171.    DBL answer_array[4];
  172.    MATRIX *matrix;
  173.  
  174.    matrix = (MATRIX *) transformation -> matrix;
  175.  
  176.    for (i = 0 ; i < 4 ; i++)
  177.       answer_array[i] = vector -> x * (*matrix)[0][i]
  178.                       + vector -> y * (*matrix)[1][i]
  179.                       + vector -> z * (*matrix)[2][i]
  180.                       + (*matrix)[3][i];
  181.  
  182.    result -> x  = answer_array[0];
  183.    result -> y  = answer_array[1];
  184.    result -> z  = answer_array[2];
  185.    }
  186.  
  187. void MInverseTransformVector (result, vector, transformation)
  188.    VECTOR *result, *vector;
  189.    TRANSFORMATION *transformation;
  190.    {
  191.    register int i;
  192.    DBL answer_array[4];
  193.    MATRIX *matrix;
  194.  
  195.    matrix = (MATRIX *) transformation -> inverse;
  196.  
  197.    for (i = 0 ; i < 4 ; i++)
  198.       answer_array[i] = vector -> x * (*matrix)[0][i]
  199.                       + vector -> y * (*matrix)[1][i]
  200.                       + vector -> z * (*matrix)[2][i]
  201.                       + (*matrix)[3][i];
  202.  
  203.    result -> x  = answer_array[0];
  204.    result -> y  = answer_array[1];
  205.    result -> z  = answer_array[2];
  206.    }
  207.  
  208. void Get_Scaling_Transformation (result, vector)
  209.    TRANSFORMATION *result;
  210.    VECTOR *vector;
  211.    {
  212.    MIdentity ((MATRIX *)result -> matrix);
  213.    (result -> matrix)[0][0] = vector -> x;
  214.    (result -> matrix)[1][1] = vector -> y;
  215.    (result -> matrix)[2][2] = vector -> z;
  216.  
  217.    MIdentity ((MATRIX *)result -> inverse);
  218.    (result -> inverse)[0][0] = 1.0 / vector -> x;
  219.    (result -> inverse)[1][1]= 1.0 / vector -> y;
  220.    (result -> inverse)[2][2] = 1.0 / vector -> z;
  221.    }
  222.  
  223. /* AAC - This is not used, so it's commented out...
  224.  
  225. void Get_Inversion_Transformation (result)
  226.    TRANSFORMATION *result;
  227.    {
  228.    MIdentity ((MATRIX *)result -> matrix);
  229.    (result -> matrix)[0][0] = -1.0;
  230.    (result -> matrix)[1][1] = -1.0;
  231.    (result -> matrix)[2][2] = -1.0;
  232.    (result -> matrix)[3][3] = -1.0;
  233.  
  234.  
  235.    (result -> inverse)[0][0] = -1.0;
  236.    (result -> inverse)[1][1] = -1.0;
  237.    (result -> inverse)[2][2] = -1.0;
  238.    (result -> inverse)[3][3] = -1.0;
  239.    }
  240. ... up to here! */
  241.  
  242. void Get_Translation_Transformation (transformation, vector)
  243.    TRANSFORMATION *transformation;
  244.    VECTOR *vector;
  245.    {
  246.    MIdentity ((MATRIX *)transformation -> matrix);
  247.    (transformation -> matrix)[3][0] = vector -> x;
  248.    (transformation -> matrix)[3][1] = vector -> y;
  249.    (transformation -> matrix)[3][2] = vector -> z;
  250.  
  251.    MIdentity ((MATRIX *)transformation -> inverse);
  252.    (transformation -> inverse)[3][0] = 0.0 - vector -> x;
  253.    (transformation -> inverse)[3][1] = 0.0 - vector -> y;
  254.    (transformation -> inverse)[3][2] = 0.0 - vector -> z;
  255.    }
  256.  
  257. void Get_Rotation_Transformation (transformation, vector)
  258.    TRANSFORMATION *transformation;
  259.    VECTOR *vector;
  260.    {
  261.    MATRIX Matrix;
  262.    VECTOR Radian_Vector;
  263.    register DBL cosx, cosy, cosz, sinx, siny, sinz;
  264.  
  265.    VScale (Radian_Vector, *vector, PI/180.0);
  266.    MIdentity ((MATRIX *)transformation -> matrix);
  267.    cosx = cos (Radian_Vector.x);
  268.    sinx = sin (Radian_Vector.x);
  269.    cosy = cos (Radian_Vector.y);
  270.    siny = sin (Radian_Vector.y);
  271.    cosz = cos (Radian_Vector.z);
  272.    sinz = sin (Radian_Vector.z);
  273.  
  274.    (transformation -> matrix) [1][1] = cosx;
  275.    (transformation -> matrix) [2][2] = cosx;
  276.    (transformation -> matrix) [1][2] = sinx;
  277.    (transformation -> matrix) [2][1] = 0.0 - sinx;
  278.    MTranspose ((MATRIX *)transformation -> inverse, (MATRIX *)transformation -> matrix);
  279.  
  280.    MIdentity ((MATRIX *)Matrix);
  281.    Matrix [0][0] = cosy;
  282.    Matrix [2][2] = cosy;
  283.    Matrix [0][2] = 0.0 - siny;
  284.    Matrix [2][0] = siny;
  285.    MTimes ((MATRIX *)transformation -> matrix, (MATRIX *)transformation -> matrix, (MATRIX *)Matrix);
  286.    MTranspose ((MATRIX *)Matrix, (MATRIX *)Matrix);
  287.    MTimes ((MATRIX *)transformation -> inverse, (MATRIX *)Matrix, (MATRIX *)transformation -> inverse);
  288.  
  289.    MIdentity ((MATRIX *)Matrix);
  290.    Matrix [0][0] = cosz;
  291.    Matrix [1][1] = cosz;
  292.    Matrix [0][1] = sinz;
  293.    Matrix [1][0] = 0.0 - sinz;
  294.    MTimes ((MATRIX *)transformation -> matrix, (MATRIX *)transformation -> matrix, (MATRIX *)Matrix);
  295.    MTranspose ((MATRIX *)Matrix, (MATRIX *)Matrix);
  296.    MTimes ((MATRIX *)transformation -> inverse, (MATRIX *)Matrix, (MATRIX *)transformation -> inverse);
  297.    }
  298.  
  299. /* AAC - This is not used so it's commented out...
  300.  
  301. void Get_Look_At_Transformation (result, Look_At, Up, Right)
  302.    TRANSFORMATION *result;
  303.    VECTOR *Look_At, *Up, *Right;
  304.    {
  305.    MIdentity ((MATRIX *)result -> inverse);
  306.    (result -> matrix)[0][0] = Right->x;
  307.    (result -> matrix)[0][1] = Right->y;
  308.    (result -> matrix)[0][2] = Right->z;
  309.    (result -> matrix)[1][0] = Up->x;
  310.    (result -> matrix)[1][1] = Up->y;
  311.    (result -> matrix)[1][2] = Up->z;
  312.    (result -> matrix)[2][0] = Look_At->x;
  313.    (result -> matrix)[2][1] = Look_At->y;
  314.    (result -> matrix)[2][2] = Look_At->z;
  315.  
  316.    MIdentity ((MATRIX *)result -> matrix);
  317.    MTranspose ((MATRIX *)result -> matrix, (MATRIX *)result -> inverse);   
  318.    }
  319.  
  320. ... up to here! */
  321.  
  322. void Compose_Transformations (Original_Transformation, New_Transformation)
  323.    TRANSFORMATION *Original_Transformation, *New_Transformation;
  324.    {
  325.    MTimes ((MATRIX *)Original_Transformation -> matrix,
  326.            (MATRIX *)Original_Transformation -> matrix,
  327.            (MATRIX *)New_Transformation -> matrix);
  328.  
  329.    MTimes ((MATRIX *)Original_Transformation -> inverse,
  330.            (MATRIX *)New_Transformation -> inverse,
  331.            (MATRIX *)Original_Transformation -> inverse);
  332.    }
  333.